/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.shape;

import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IVector;


/**
*A class representing a shape function for the H20 hexahedral element.
*
*@author Lucas, Marcelo & Pitangueira, Roque
*@version 1.0
*@since September 2004
*/

public class H20 extends ShapeC0
{
	private static final long serialVersionUID = 1L;

	/** Returns the IVector containing the values of shape function evalueted in provided points.
	*@param g The vector containing the coordinates which the shape function will be evalueted.
	*@param cN The matrix containing nodal coordinates in cartesian system.
	*@return The IVector containing the values of shape function evalueted in provided points.
	*/
	public IVector getShapeFunction(double[] g, IMatrix cN) 
	{
		double a = g[0]; //xi
		double b = g[1]; //eta
		double c = g[2]; //zeta
		
		IVector n = new IVector(20);
		
		double n0 = ((0.125)*(1-a)*(1-b)*(1-c)*(-2-a-b-c));
		double n1 = ((0.25)*(1-(a*a))*(1-b)*(1-c));
		double n2 = ((0.125)*(1+a)*(1-b)*(1-c)*(-2+a-b-c));
		double n3 = ((0.25)*(1+a)*(1-b*b)*(1-c));
		double n4 = ((0.125)*(1+a)*(1+b)*(1-c)*(-2+a+b-c));
		double n5 = ((0.25)*(1-a*a)*(1+b)*(1-c));
		double n6 = ((0.125)*(1-a)*(1+b)*(1-c)*(-2-a+b-c));
		double n7 = ((0.25)*(1-a)*(1-b*b)*(1-c));
		double n8 = ((0.25)*(1-a)*(1-b)*(1-c*c));
		double n9 = ((0.25)*(1+a)*(1-b)*(1-c*c));
		double n10 = ((0.25)*(1+a)*(1+b)*(1-c*c));
		double n11 = ((0.25)*(1-a)*(1+b)*(1-c*c));
		double n12 = ((0.125)*(1-a)*(1-b)*(1+c)*(-2-a-b+c));
		double n13 = ((0.25)*(1-a*a)*(1-b)*(1+c));
		double n14 = ((0.125)*(1+a)*(1-b)*(1+c)*(-2+a-b+c));
		double n15 = ((0.25)*(1+a)*(1-b*b)*(1+c));
		double n16 = ((0.125)*(1+a)*(1+b)*(1+c)*(-2+a+b+c));
		double n17 = ((0.25)*(1-a*a)*(1+b)*(1+c));
		double n18 = ((0.125)*(1-a)*(1+b)*(1+c)*(-2-a+b+c));
		double n19 = ((0.25)*(1-a)*(1-b*b)*(1+c));
		
		n.setElement(0,n0);
		n.setElement(1,n1);
		n.setElement(2,n2);
		n.setElement(3,n3);
		n.setElement(4,n4);
		n.setElement(5,n5);
		n.setElement(6,n6);
		n.setElement(7,n7);
		n.setElement(8,n8);
		n.setElement(9,n9);
		n.setElement(10,n10);
		n.setElement(11,n11);
		n.setElement(12,n12);
		n.setElement(13,n13);
		n.setElement(14,n14);
		n.setElement(15,n15);
		n.setElement(16,n16);
		n.setElement(17,n17);
		n.setElement(18,n18);
		n.setElement(19,n19);
		
		return (n);
	}
	
	/** Returns the IMatrix containing the values of shape function derived in xi and eta evalueted in provided points.
	*@param g The vector containing the coordinates which the shape function will be evalueted.
	*@param cN The matrix containing nodal coordinates in cartesian system.
	*@return The IMatrix containing the values of shape function derived in xi and eta evalueted in provided points.
	*/
	public IMatrix getDerivedShapeFunction(double[] g, IMatrix cN) 
	{
		double a = g[0];
		double b = g[1];
		double c = g[2];
		
		IMatrix dl = new IMatrix(3,20);
		
	//derivadas em relacao a xi (a = xi e b = eta e c = zeta)
		
		double dxi0 = ((-0.125)*(1-b)*(1-c)*(-1-2*a-b-c));
		double dxi1 = ((-0.5)*(a)*(1-b)*(1-c));
		double dxi2 = ((0.125)*(1-b)*(1-c)*(-1+2*a-b-c));
		double dxi3 = ((0.25)*(1-b*b)*(1-c));
		double dxi4 = ((0.125)*(1+b)*(1-c)*(-1+2*a+b-c));
		double dxi5 = ((-0.5)*(a)*(1+b)*(1-c));
		double dxi6 = ((-0.125)*(1+b)*(1-c)*(-1-2*a+b-c));
		double dxi7 = ((-0.25)*(1-b*b)*(1-c));
		double dxi8 = ((-0.25)*(1-b)*(1-c*c));
		double dxi9 = ((0.25)*(1-b)*(1-c*c));
		double dxi10 = ((0.25)*(1+b)*(1-c*c));
		double dxi11 = ((-0.25)*(1+b)*(1-c*c));
		double dxi12 = ((-0.125)*(1-b)*(1+c)*(-1-2*a-b+c));
		double dxi13 = ((-0.5)*(a)*(1-b)*(1+c));
		double dxi14 = ((0.125)*(1-b)*(1+c)*(-1+2*a-b+c));
		double dxi15 = ((0.25)*(1-b*b)*(1+c));
		double dxi16 = ((0.125)*(1+b)*(1+c)*(-1+2*a+b+c));
		double dxi17 = ((-0.5)*(a)*(1+b)*(1+c));
		double dxi18 = ((-0.125)*(1+b)*(1+c)*(-1-2*a+b+c));
		double dxi19 = ((-0.25)*(1-b*b)*(1+c));
		
	//derivadas em relacao a eta (a = xi e b = eta e c = zeta)	
		
		double deta0 = ((-0.125)*(1-a)*(1-c)*(-1-a-2*b-c));
		double deta1 = ((-0.25)*(1-(a*a))*(1-c));
		double deta2 = ((-0.125)*(1+a)*(1-c)*(-1+a-2*b-c));
		double deta3 = ((-0.5)*(b)*(1+a)*(1-c));
		double deta4 = ((0.125)*(1+a)*(1-c)*(-1+a+2*b-c));
		double deta5 = ((0.25)*(1-(a*a))*(1-c));
		double deta6 = ((0.125)*(1-a)*(1-c)*(-1-a+2*b-c));
		double deta7 = ((-0.5)*(b)*(1-a)*(1-c));
		double deta8 = ((-0.25)*(1-a)*(1-(c*c)));
		double deta9 = ((-0.25)*(1+a)*(1-(c*c)));
		double deta10 = ((0.25)*(1+a)*(1-(c*c)));
		double deta11 = ((0.25)*(1-a)*(1-(c*c)));
		double deta12 = ((-0.125)*(1-a)*(1+c)*(-1-a-2*b+c));
		double deta13 = ((-0.25)*(1-(a*a))*(1+c));
		double deta14 = ((-0.125)*(1+a)*(1+c)*(-1+a-2*b+c));
		double deta15 = ((-0.5)*(b)*(1+a)*(1+c));
		double deta16 = ((0.125)*(1+a)*(1+c)*(-1+a+2*b+c));
		double deta17 = ((0.25)*(1-(a*a))*(1+c));
		double deta18 = ((0.125)*(1-a)*(1+c)*(-1-a+2*b+c));
		double deta19 = ((-0.5)*(b)*(1-a)*(1+c));
		
	//derivadas em relacao a zeta (a = xi e b = eta e c = zeta)		
		
		double dzeta0 = ((-0.125)*(1-a)*(1-b)*(-1-a-b-2*c));
		double dzeta1 = ((-0.25)*(1-(a*a))*(1-b));
		double dzeta2 = ((-0.125)*(1+a)*(1-b)*(-1+a-b-2*c));
		double dzeta3 = ((-0.25)*(1+a)*(1-(b*b)));
		double dzeta4 = ((-0.125)*(1+a)*(1+b)*(-1+a+b-2*c));
		double dzeta5 = ((-0.25)*(1-(a*a))*(1+b));
		double dzeta6 = ((-0.125)*(1-a)*(1+b)*(-1-a+b-2*c));
		double dzeta7 = ((-0.25)*(1-a)*(1-(b*b)));
		double dzeta8 = ((-0.5*c)*(1-a)*(1-b));
		double dzeta9 = ((-0.5*c)*(1+a)*(1-b));
		double dzeta10 = ((-0.5*c)*(1+a)*(1+b));
		double dzeta11 = ((-0.5*c)*(1-a)*(1+b));
		double dzeta12 = ((0.125)*(1-a)*(1-b)*(-1-a-b+2*c));
		double dzeta13 = ((0.25)*(1-(a*a))*(1-b));
		double dzeta14 = ((0.125)*(1+a)*(1-b)*(-1+a-b+2*c));
		double dzeta15 = ((0.25)*(1+a)*(1-(b*b)));
		double dzeta16 = ((0.125)*(1+a)*(1+b)*(-1+a+b+2*c));
		double dzeta17 = ((0.25)*(1-(a*a))*(1+b));
		double dzeta18 = ((0.125)*(1-a)*(1+b)*(-1-a+b+2*c));
		double dzeta19 = ((0.25)*(1-a)*(1-(b*b)));
		
		
	//derivadas em relacao a xi na linha 0 da IMatrix
		dl.setElement(0,0,dxi0 );
		dl.setElement(0,1,dxi1 );
		dl.setElement(0,2,dxi2 );
		dl.setElement(0,3,dxi3 );
		dl.setElement(0,4,dxi4 );
		dl.setElement(0,5,dxi5 );
		dl.setElement(0,6,dxi6 );
		dl.setElement(0,7,dxi7 );
		dl.setElement(0,8,dxi8 );
		dl.setElement(0,9,dxi9 );
		dl.setElement(0,10,dxi10 );
		dl.setElement(0,11,dxi11 );
		dl.setElement(0,12,dxi12 );
		dl.setElement(0,13,dxi13 );
		dl.setElement(0,14,dxi14 );
		dl.setElement(0,15,dxi15 );
		dl.setElement(0,16,dxi16 );
		dl.setElement(0,17,dxi17 );
		dl.setElement(0,18,dxi18 );
		dl.setElement(0,19,dxi19 );
	//derivadas em relacao a eta na linha 1 da IMatrix		
		dl.setElement(1,0, deta0);
		dl.setElement(1,1, deta1);
		dl.setElement(1,2, deta2);
		dl.setElement(1,3, deta3);
		dl.setElement(1,4, deta4);
		dl.setElement(1,5, deta5);
		dl.setElement(1,6, deta6);
		dl.setElement(1,7, deta7);
		dl.setElement(1,8, deta8);
		dl.setElement(1,9, deta9);
		dl.setElement(1,10, deta10);
		dl.setElement(1,11, deta11);
		dl.setElement(1,12, deta12);
		dl.setElement(1,13, deta13);
		dl.setElement(1,14, deta14);
		dl.setElement(1,15, deta15);
		dl.setElement(1,16, deta16);
		dl.setElement(1,17, deta17);
		dl.setElement(1,18, deta18);
		dl.setElement(1,19, deta19);
	//derivadas em relacao a zeta na linha 2 da IMatrix		
		dl.setElement(2,0, dzeta0);
		dl.setElement(2,1, dzeta1);
		dl.setElement(2,2, dzeta2);
		dl.setElement(2,3, dzeta3);
		dl.setElement(2,4, dzeta4);
		dl.setElement(2,5, dzeta5);
		dl.setElement(2,6, dzeta6);
		dl.setElement(2,7, dzeta7);
		dl.setElement(2,8, dzeta8);
		dl.setElement(2,9, dzeta9);
		dl.setElement(2,10, dzeta10);
		dl.setElement(2,11, dzeta11);
		dl.setElement(2,12, dzeta12);
		dl.setElement(2,13, dzeta13);
		dl.setElement(2,14, dzeta14);
		dl.setElement(2,15, dzeta15);
		dl.setElement(2,16, dzeta16);
		dl.setElement(2,17, dzeta17);
		dl.setElement(2,18, dzeta18);
		dl.setElement(2,19, dzeta19);
		
		return (dl);
	}
	
	/** Return the IMatrix containing nodal coordinates of this shape in natural system.
	*@return natCoords The IMatrix with nodal coordinates of this shape in natural system.
	*/
	public IMatrix getNaturalNodalCoords()
	{
		IMatrix natCoords = new IMatrix(3,20);
		
	//coordenadas naturais de xi
		natCoords.setElement(0,0,-1);
		natCoords.setElement(0,1,0);
		natCoords.setElement(0,2,1);
		natCoords.setElement(0,3,1);
		natCoords.setElement(0,4,1);
		natCoords.setElement(0,5,0);
		natCoords.setElement(0,6,-1);
		natCoords.setElement(0,7,-1);
		natCoords.setElement(0,8,-1);
		natCoords.setElement(0,9,1);
		natCoords.setElement(0,10,1);
		natCoords.setElement(0,11,-1);
		natCoords.setElement(0,12,-1);
		natCoords.setElement(0,13,0);
		natCoords.setElement(0,14,1);
		natCoords.setElement(0,15,1);
		natCoords.setElement(0,16,1);
		natCoords.setElement(0,17,0);
		natCoords.setElement(0,18,-1);
		natCoords.setElement(0,19,-1);
	//coordenadas naturais de eta
		natCoords.setElement(1,0,-1);
		natCoords.setElement(1,1,-1);
		natCoords.setElement(1,2,-1);
		natCoords.setElement(1,3,0);
		natCoords.setElement(1,4,1);
		natCoords.setElement(1,5,1);
		natCoords.setElement(1,6,1);
		natCoords.setElement(1,7,0);
		natCoords.setElement(1,8,-1);
		natCoords.setElement(1,9,-1);
		natCoords.setElement(1,10,1);
		natCoords.setElement(1,11,1);
		natCoords.setElement(1,12,-1);
		natCoords.setElement(1,13,-1);
		natCoords.setElement(1,14,-1);
		natCoords.setElement(1,15,0);
		natCoords.setElement(1,16,1);
		natCoords.setElement(1,17,1);
		natCoords.setElement(1,18,1);
		natCoords.setElement(1,19,0);
	//coordenadas naturais de zeta
		natCoords.setElement(2,0,-1);
		natCoords.setElement(2,1,-1);
		natCoords.setElement(2,2,-1);
		natCoords.setElement(2,3,-1);
		natCoords.setElement(2,4,-1);
		natCoords.setElement(2,5,-1);
		natCoords.setElement(2,6,-1);
		natCoords.setElement(2,7,-1);
		natCoords.setElement(2,8,0);
		natCoords.setElement(2,9,0);
		natCoords.setElement(2,10,0);
		natCoords.setElement(2,11,0);
		natCoords.setElement(2,12,1);
		natCoords.setElement(2,13,1);
		natCoords.setElement(2,14,1);
		natCoords.setElement(2,15,1);
		natCoords.setElement(2,16,1);
		natCoords.setElement(2,17,1);
		natCoords.setElement(2,18,1);
		natCoords.setElement(2,19,1);
		
			return (natCoords);
	}

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.shape.Shape3D#getType()
     */
    public String getType() {
        return "H20";
    }
	
}

